//
// Created by none98 on 2021/9/23.
//

#include <spdlog/spdlog.h>
#include "ChooseRoleService.h"
#include "ChooseRole.pb.h"
#include "../Context.h"
#include "../PlayerBin.h"
#include "GameServer.h"

void ChooseRoleService::Serve(TcpConnectionPtr conn, std::string message) {
    ChooseRoleRequest chooseRoleRequest;
    ChooseRoleResponse chooseRoleResponse;
    std::string response;

    chooseRoleRequest.ParseFromString(message);
    Context* context = static_cast<Context*>(conn->GetContext());

    if(context->GetUid()!=chooseRoleRequest.token()){
        spdlog::info("token authority failed in ChooseRoleReq");
        chooseRoleResponse.set_status(GameServer::StatusCode::authFailed);
    }else{
        if(context->GetPlayerBin()->GetName()!="") context->Synchronize();
        //handle request in mysql
        sql::Connection* sqlConn = context->GetDbConnection();
        try{
            std::string sql = "SELECT * FROM game_user_role where uid=? and rolename=?";
            std::unique_ptr<sql::PreparedStatement> statement(sqlConn->prepareStatement(sql));
            statement->setInt64( 1,chooseRoleRequest.token() );
            statement->setString(2, chooseRoleRequest.rolename());
            std::unique_ptr<sql::ResultSet> results(statement->executeQuery());
            if(results->next()){
                int x = results->getInt("x");
                int y = results->getInt("y");
                int z = results->getInt("z");
                context->GetPlayerBin()->GetPosition()->Set(x,y,z);
                context->GetPlayerBin()->SetName(chooseRoleRequest.rolename());
                chooseRoleResponse.set_status(GameServer::StatusCode::success);
                chooseRoleResponse.set_x(x);
                chooseRoleResponse.set_y(y);
                chooseRoleResponse.set_z(z);
                spdlog::info("uid:{} choose role {}",chooseRoleRequest.token(),chooseRoleRequest.rolename());
            }else{
                chooseRoleResponse.set_status(GameServer::StatusCode::failed);
                spdlog::error("uid:{},choose the unexisted role",chooseRoleRequest.token());
            }
        }catch(sql::SQLException &e){
            chooseRoleResponse.set_status(GameServer::StatusCode::failed);
            spdlog::error("uid:{},{}",chooseRoleRequest.token(),e.what());
        }
        context->CloseDbConnection(sqlConn);
        //set chooseRoleResponse
    }

    std::string proto = std::move(chooseRoleResponse.SerializeAsString());
    int length = htonl(8+proto.size());
    int type = htonl(GameServer::ProtoType::chooseRoleRes);
    response.append(reinterpret_cast<char*>(&length),4);
    response.append(reinterpret_cast<char*>(&type),4);
    response.append(proto);
    conn->Send(response);
}
